<template>
  <el-dialog :close-on-click-modal="false || noSubmit" :title="title || innerTitle" :visible.sync="visible"
    :custom-class="customClass ? customClass : 'dialog_small'" v-bind="$attrs" v-on="$listeners">
    <div v-loading="loading" class="flex_col" style="max-height: 85vh;">
      <div style="flex:1;overflow-y:auto;overflow-x: hidden;">
        <superForm ref="form" v-bind="form" :label-width="$globalCss.formLabelWidth_default">
          <template v-slot:[item.slot]="scope" v-for="item in form.model">
            <slot :name="item.slot" v-bind="scope"></slot>
          </template>
        </superForm>
      </div>
      <slot name="dialog_bottom"></slot>
      <div slot="footer" class="dialog_button_footer">
        <slot name="dialog_button_footer"></slot>
        <el-button type="primary" @click="submitForm()" v-if="!noSubmit">
          {{ $tt(innerOption.submitSureText || submitSureText) }}</el-button>
        <el-button @click="visible = false">{{ $tt(cancelText) }}</el-button>
      </div>
    </div>
  </el-dialog>
</template>

<script>
import superForm from './super-form.vue'

export default {
  name: 'dialog-form',
  components: { superForm, },
  data() {
    return {
      visible: false,
      loading: false,
      params: null,
      option: null,
      innerTitle: null,
      innerOption: {

      },
    }
  },
  props: {
    form: Object,
    detailUrl: String,
    detailDataHandle: Function,
    submitUrl: String,
    submitDataHandle: Function,
    submitType: {
      type: String,
      default: "json",
    },
    title: String,
    customClass: String,
    noSubmit: Boolean,
    submitSureText: {
      type: String,
      default: "label_confirm"
    },
    cancelText: {
      type: String,
      default: "label_cancel"
    },
  },

  methods: {
    getRef(key) {
      return this.$refs.form.getRef(key)
    },
    getFormData() {
      return this.$refs.form.getFormData()
    },
    getData() {
      return this.$refs.form.getData()
    },
    clearValidate(e) {
      return this.$refs.form.clearValidate(e)
    },
    validate(e) {
      return this.$refs.form.validate(e)
    },
    resetFields(e) {
      return this.$refs.form.resetFields(e)
    },
    showNew({ data, params, onlySetData, beforeCall, submitUrl, submitType, detailUrl, detailDataHandle, submitDataHandle, submitCall, submitSureText, title, noReset, detailConfig }) {
      this.visible = true
      this.innerTitle = title
      this.innerOption = {
        submitUrl, submitType, detailUrl, detailDataHandle, submitDataHandle, submitCall, submitSureText,
      }





      if (!noReset && this.$refs.form) this.$refs.form.resetFields()
      let defaultData = Object.assign({}, _.cloneDeep(this.form.default))

      if (data) {
        Object.assign(defaultData, _.cloneDeep(data))
      }

      if (!onlySetData) {
        if (beforeCall) {
          this.loading = true
          beforeCall().then((beforeReturn) => {
            this.loading = false
            const handle = beforeReturn.detailDataHandle || this.innerOption.detailDataHandle || this.detailDataHandle
            const url = this.innerOption.detailUrl || this.detailUrl
            if (url) {
              this.getData(url, beforeReturn.params || params, handle, defaultData, detailConfig)
            } else if (handle) {
              defaultData = handle(defaultData)
              this.$nextTick(() => {
                this.$refs.form.setData(defaultData)
                this.$refs.form.clearValidate()
              })
            }
          }).catch(e => {

          })
        } else {
          const url = this.innerOption.detailUrl || this.detailUrl
          const handle = this.innerOption.detailDataHandle || this.detailDataHandle
          if (url) {
            this.getData(url, params, handle, defaultData, detailConfig)
          } else if (handle) {
            defaultData = handle(defaultData)
          }
        }
      }


      this.$nextTick(() => {
        this.$refs.form.setData(defaultData)
        this.$refs.form.clearValidate()

      })

    },

    getData(url, params, handle, defaultData, netConfig) {
      if (!url) return

      this.loading = true
      let ajaxConfig = {
        url,
        data: params,
        success: (responseData) => {
          let resdata = responseData.data
          if (handle) {
            resdata = handle(resdata)
          }
          this.$nextTick(() => {
            this.$refs.form.setData(Object.assign({}, defaultData, resdata))
            this.$refs.form.clearValidate()
          })
        },
        failure: () => {
          this.$nextTick(() => {
            this.$refs.form.setData(Object.assign({}, defaultData, _.cloneDeep(this.form.default)))
            this.$refs.form.clearValidate()
          })
        },
        complete: () => {
          this.loading = false
        }
      }
      if (netConfig) {
        Object.assign(ajaxConfig, netConfig)
      }
      this.$ajax(ajaxConfig);

    },


    show(data, option, title) {
      this.visible = true
      this.option = option
      this.innerTitle = title
      this.reinitData(data, option)
    },
    reinitData(data, option) {
      if (!option) option = this.option
      if (this.$refs.form) this.$refs.form.resetFields()
      if (data) {
        if (option == true || (option && option.setData == true)) {
          this.$nextTick(() => {
            this.$refs.form.setData(Object.assign({}, _.cloneDeep(this.form.default), _.cloneDeep(data)))
            this.$refs.form.clearValidate()
          })
        } else {
          this.loading = true

          let ajaxConfig = {
            url: this.detailUrl,
            data: Object.assign({}, data),
            success: (responseData) => {
              let resdata = this.detailDataHandle ? this.detailDataHandle(responseData.data) : responseData.data
              if (option && option.detailDataHandle) {
                resdata = option.detailDataHandle(resdata)
              }
              this.$nextTick(() => {
                this.$refs.form.setData(Object.assign({}, _.cloneDeep(this.form.default), resdata))
                this.$refs.form.clearValidate()
              })
            },
            failure: () => {
              this.$nextTick(() => {
                this.$refs.form.setData(Object.assign({}, _.cloneDeep(this.form.default)))
                this.$refs.form.clearValidate()
              })

            },
            complete: () => {
              this.loading = false
            }
          }
          if (option && option.detailConfig) {
            Object.assign(ajaxConfig, option.detailConfig)
          }
          this.$ajax(ajaxConfig);
        }
      }
    },
    submitForm() {
      if (this.$formRulesValidate) {
        this.$formRulesValidate({
          formRef: this.$refs.form,
          rules: this.form.rules,
          success: () => {
            this.ajaxSubmitForm();
          }
        })
      } else {
        this.$refs.form.validate((valid, list) => {
          if (valid) {
            this.ajaxSubmitForm();
          } else {
            this.$message.error(this.$tt('form_validate_error'))
            return false;
          }
        });
      }


    },
    submitCallResult(close, emit, tip,) {
      if (tip) {
        this.$message(tip)
      }
      if (emit) {
        this.$emit('afterSubmitSuccess', this.$refs.form.getData())
      }
      if (close) {
        this.visible = false
      }

    },
    ajaxSubmitForm() {
      if (this.$clickFast()) return this.$message.warning(this.$tt('tip_please_no_operate_fast'))


      if (this.innerOption.submitUrl || this.submitUrl) {
        let data = this.submitDataHandle ? this.submitDataHandle(this.$refs.form.getFormData()) : this.$refs.form.getFormData()
        if (this.option && this.option.submitDataHandle) {
          data = this.option.submitDataHandle(data)
        }
        if (this.innerOption.submitDataHandle) {
          data = this.innerOption.submitDataHandle(data)
        }

        let type = this.innerOption.submitType || this.submitType

        let ajaxConfig = {
          url: this.innerOption.submitUrl || this.submitUrl,
          type,
          data,
          loading: this.$tt('tip_submiting'),
          success: (responseData) => {
            if (this.innerOption.submitCall) {
              this.innerOption.submitCall(responseData, this.$refs.form.getData(), this.submitCallResult)
            } else {
              this.submitCallResult(true, true, { message: this.$tt("tip_submit_success"), type: "success" },)
            }

          },
          complete: () => {
          }
        }
        if (this.option && this.option.submitConfig) {
          Object.assign(ajaxConfig, this.option.submitConfig)
        }
        this.$ajax(ajaxConfig);
      } else {
        if (this.innerOption.submitCall) {
          this.innerOption.submitCall(null, this.$refs.form.getData(), this.submitCallResult)
        } else {
          this.submitCallResult(true, true, false,)
        }

      }

    },

    set(key, value) {
      this.$refs.form.set(key, value)
    },



  }
}
</script>
